package com.iflysse.services.impl;

import com.iflysse.common.ResultEnum;
import com.iflysse.dao.ChapterDao;
import com.iflysse.dao.CourseDao;
import com.iflysse.dao.TaskDao;
import com.iflysse.dao.TeachingClassDao;
import com.iflysse.pojo.bo.CommonBoResp;
import com.iflysse.pojo.bo.common.PageBeanBoResp;
import com.iflysse.pojo.bo.req.StudentIdBoReq;
import com.iflysse.pojo.bo.req.StudentIdPageBoReq;
import com.iflysse.pojo.bo.req.TaskBoReq;
import com.iflysse.pojo.bo.req.TaskIdBoReq;
import com.iflysse.pojo.bo.resp.*;
import com.iflysse.pojo.po.common.CommonPoResp;
import com.iflysse.pojo.po.req.*;
import com.iflysse.pojo.po.resp.StudentTaskPoResp;
import com.iflysse.pojo.po.resp.TaskDetailPoResp;
import com.iflysse.pojo.po.resp.TaskPoResp;
import com.iflysse.pojo.po.resp.TaskResourceCompletePoResp;
import com.iflysse.services.TaskService;
import com.iflysse.util.CommonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Service
public class TaskServiceImpl implements TaskService {
    @Autowired
    TaskDao taskDao;
    @Autowired
    ChapterDao chapterDao;
    @Autowired
    TeachingClassDao teachingClassDao;
    @Autowired
    CourseDao courseDao;

    /**
     * 发布任务
     *
     * @param taskBoReq 任务实体
     * @return
     */
    @Transactional
    @Override
    public CommonBoResp publishTask(TaskBoReq taskBoReq) throws SQLException {
        CommonBoResp commonBoResp = new CommonBoResp();
        try {

            String uuid = UUID.randomUUID().toString();
            TaskPoReq taskPoReq = CommonUtil.objToObj(taskBoReq, TaskPoReq.class);
            taskPoReq.setTaskId(uuid);
            int totalNumOfChapter = 0;
            for (String cid : taskBoReq.getChapterIdList()) {

                ChapterIdPoReq chapterIdPoReq = new ChapterIdPoReq();
                chapterIdPoReq.setChapterId(cid);
                int numOfChapter = chapterDao.getResourceNumberOfChapter(chapterIdPoReq);
                totalNumOfChapter += numOfChapter;

            }
            taskPoReq.setResourceNumberOfChapter(totalNumOfChapter);
            //添加任务
            CommonPoResp addTaskResp =new CommonPoResp();
            int i = taskDao.addTask(taskPoReq);
            CommonUtil.printToPoResult(addTaskResp,i);
            TaskDetailPoReq taskDetailPoReq = new TaskDetailPoReq();
            taskDetailPoReq.setTaskId(uuid);
            taskDetailPoReq.setChapterIdList(taskBoReq.getChapterIdList());
            //添加任务详情,将任务中的章添加到数据库
            CommonPoResp addDetailResp =new CommonPoResp();
            int update = taskDao.addTaskDetail4Chapter(taskDetailPoReq);
            CommonUtil.printToPoResult(addDetailResp,update);
            int result = (addTaskResp.getCode() == ResultEnum.SUCCESS.getCode()
                    && addDetailResp.getCode() == ResultEnum.SUCCESS.getCode()) ? 1:0;
            CommonUtil.printToBoResult(commonBoResp,result);
        } catch (SQLException throwables) {
            //System.out.println("错误,事务回滚...");
            throwables.printStackTrace();
            CommonUtil.printToBoResult(commonBoResp,0);
        }

        return commonBoResp;
    }

    /**
     * 学生首页展示,获取当前学生前4个待学习任务列表
     *
     * @param studentIdBoReq
     * @return
     */
    @Override
    public TaskListBoResp getTop4WaitingTaskByStudentId(StudentIdBoReq studentIdBoReq) throws SQLException {
        TaskListBoResp taskListBoResp = new TaskListBoResp();
        //获取学生待学习的任务编号列表
        List<String> orderedWatingTaskIds = getOrderedWatingTaskIds(studentIdBoReq.getStudentId());
        if(orderedWatingTaskIds.size() >0){

            //根据任务编号查询任务
            List<TaskPoResp> taskPoRespList = taskDao.getTop4OrderedWatingTaskByTaskIds(orderedWatingTaskIds);
            List<TaskBoResp> taskBoRespList = new ArrayList<>();
            //将taskPoRespList数据需要的数据补全
            createTaskBoResp(studentIdBoReq, taskBoRespList, taskPoRespList);
            taskListBoResp.setTaskBoRespList(taskBoRespList);

        }
        //根据任务查询该学生的完成情况
        return taskListBoResp;
    }

    /**
     * 遍历task列表,将task中的相关信息补全
     * @param studentIdBoReq  学生编号
     * @param taskBoRespList 任务service层列表
     * @param taskPoRespList 任务dao层返回列表
     * @throws SQLException
     */
    private void createTaskBoResp(StudentIdBoReq studentIdBoReq, List<TaskBoResp> taskBoRespList, List<TaskPoResp> taskPoRespList) throws SQLException {

        //System.out.println(taskPoRespList);

        for (int i = 0; i < taskPoRespList.size(); i++) {
            TaskPoResp taskPoResp = taskPoRespList.get(i);
            TaskBoResp taskBoResp = CommonUtil.objToObj(taskPoResp, TaskBoResp.class);
            //设置taskBoResp的其他属性
            //获取当前学生的的该任务完成情况
            StudentIdAndTaskIdPoReq studentIdAndTaskIdPoReq = new StudentIdAndTaskIdPoReq();
            studentIdAndTaskIdPoReq.setStudentId(studentIdBoReq.getStudentId());
            studentIdAndTaskIdPoReq.setTaskId(taskPoResp.getTaskId());
            Integer haveLearnNumber = taskDao.getLearnedResourceNumberByStudentIdAndTaskId(studentIdAndTaskIdPoReq);
            taskBoResp.setDoneResourceNumberOfTask(haveLearnNumber == null ? 0 : haveLearnNumber.intValue());
            //获取当前班级总人数
            int amountOfStudent = teachingClassDao.getStudentAmountByTeachingClassId(taskPoResp.getTeachingClassId());
            taskBoResp.setTotalNumberOfStudents(amountOfStudent);
            //获取当前任务课程封面
            //根据教学班级得到课程编号
            String courseId = teachingClassDao.getCourseIdByTeachingClassId(taskPoResp.getTeachingClassId());
            //根据课程编号得到课程封面路径
            CourseIdPoReq courseIdPoReq = new CourseIdPoReq();
            courseIdPoReq.setCourseId(courseId);
            String coverPath = courseDao.getCourseCoverByCourseId(courseIdPoReq);
            taskBoResp.setPhotoPath(coverPath);
            taskBoRespList.add(taskBoResp);
        }
    }


    /**
     * 得到学生没有学习的任务列表
     * @param studentId
     * @return
     * @throws SQLException
     */
    private List<String> getOrderedWatingTaskIds(String studentId) throws SQLException {
        List<String> orderedWatingTaskIdsByTeachingIds = new ArrayList<>();
        TaskListBoResp taskListBoResp = new TaskListBoResp();
        //获取当前学生的所有班级
        List<String> teachingClassIds = teachingClassDao.getTeachingClassIdsByStudentId(studentId);
        if(teachingClassIds.size() >0) {
            //根据学生编号获取当前学生已经完成的任务编号列表
            List<String> completeTaskIds = taskDao.getCompleteTaskIdsByStudentId(studentId);

            //得到没有学习的任务编号
            orderedWatingTaskIdsByTeachingIds = taskDao.getOrderedWatingTaskIdsByTeachingIds(teachingClassIds, completeTaskIds);
        }
        return orderedWatingTaskIdsByTeachingIds;
    }





    /**
     * 更多现实学习任务,获取当前学生所有待学习任务列表
     * 分页展示,需要提供分页数据
     *
     * @param studentIdPageBoReq
     * @return
     */
    @Override
    public PageBeanBoResp<TaskBoResp> getWaitingTaskByStudentId(StudentIdPageBoReq studentIdPageBoReq) throws SQLException {
        int pageIndex = studentIdPageBoReq.getPageBeanBoReq().getPageIndex();
        int pageSize = studentIdPageBoReq.getPageBeanBoReq().getPageSize();

        List<String> orderedWatingTaskIds = getOrderedWatingTaskIds(studentIdPageBoReq.getStudentId());
        PageBeanBoResp<TaskBoResp> pageBeanBoResp =
                new PageBeanBoResp<TaskBoResp>(pageIndex,pageSize,orderedWatingTaskIds.size());
        //存在待学习任务列表
        if(orderedWatingTaskIds.size()>0){
            List<TaskPoResp> pagedOrderedWatingTasks = taskDao.getPagedOrderedWatingTaskByTaskIds(
                    orderedWatingTaskIds,
                    pageIndex,
                    pageSize);

            List<TaskBoResp> taskBoRespList = new ArrayList<>();

            //封装list对象,补全一些属性
            createTaskBoResp(studentIdPageBoReq,taskBoRespList,pagedOrderedWatingTasks);
            pageBeanBoResp.setList(taskBoRespList);

        }


        return pageBeanBoResp;
    }




    /**
     * 学生首页展示,获取当前学生前4个已学习任务列表
     *
     * @param studentIdBoReq
     * @return
     */
    @Override
    public CompleteTaskListBoResp getTop4CompleteTaskByStudentId(StudentIdBoReq studentIdBoReq) throws SQLException {
        CompleteTaskListBoResp completeTaskListBoResp = new CompleteTaskListBoResp();
        //得到学生已完成任务列表
        List<String> orderedCompleteTaskIds = getOrderedCompleteTaskIds(studentIdBoReq.getStudentId());
        if(orderedCompleteTaskIds .size() > 0){
            //根据任务编号查询任务,和待完成任务使用同一个dao接口
            List<TaskPoResp> taskPoRespList = taskDao.getTop4OrderedWatingTaskByTaskIds(orderedCompleteTaskIds);

            List<CompleteTaskBoResp> completeTaskBoRespList = getCompleteTaskBoResps(taskPoRespList);


            completeTaskListBoResp.setCompleteTaskBoRespList(completeTaskBoRespList);
        }

        return completeTaskListBoResp;
    }

    /**
     * 将任务dao对象转换为service对象,并且添加额外数据
     * @param taskPoRespList
     * @return
     * @throws SQLException
     */
    private List<CompleteTaskBoResp> getCompleteTaskBoResps(List<TaskPoResp> taskPoRespList) throws SQLException {
        List<CompleteTaskBoResp> completeTaskBoRespList = new ArrayList<>();

        for(int i = 0; i< taskPoRespList.size(); i++){
            TaskPoResp taskPoResp = taskPoRespList.get(i);
            CompleteTaskBoResp completeTaskBoResp = CommonUtil.objToObj(taskPoResp, CompleteTaskBoResp.class);

            //根据教学班级得到课程编号
            String courseId = teachingClassDao.getCourseIdByTeachingClassId(taskPoResp.getTeachingClassId());
            //根据课程编号得到课程封面路径
            CourseIdPoReq courseIdPoReq = new CourseIdPoReq();
            courseIdPoReq.setCourseId(courseId);
            String coverPath = courseDao.getCourseCoverByCourseId(courseIdPoReq);
            //设置封面
            completeTaskBoResp.setPhotoPath(coverPath);

            completeTaskBoRespList.add(completeTaskBoResp);

            //获取知识点成绩.....
            //TODO 获取知识点成绩
        }
        return completeTaskBoRespList;
    }

    /**
     * 更多现实学习任务,获取当前学生所有待学习任务列表
     * 分页展示,需要提供分页数据
     *
     * @param studentIdPageBoReq
     * @return
     */
    @Override
    public PageBeanBoResp<CompleteTaskBoResp> getCompleteTaskByStudentId(StudentIdPageBoReq studentIdPageBoReq) throws SQLException {
        CompleteTaskListBoResp completeTaskListBoResp = new CompleteTaskListBoResp();
        //得到学生已完成任务列表
        List<String> orderedCompleteTaskIds = getOrderedCompleteTaskIds(studentIdPageBoReq.getStudentId());
        int pageIndex = studentIdPageBoReq.getPageBeanBoReq().getPageIndex();
        int pageSize = studentIdPageBoReq.getPageBeanBoReq().getPageSize();
        //创建分页对象
        PageBeanBoResp<CompleteTaskBoResp> pageBeanBoResp = new PageBeanBoResp<>(pageIndex,pageSize,orderedCompleteTaskIds.size());

        if(orderedCompleteTaskIds .size() > 0) {

            //根据任务编号查询任务,和待完成任务使用同一个dao接口
            List<TaskPoResp> taskPoRespList = taskDao.getPagedOrderedWatingTaskByTaskIds(
                    orderedCompleteTaskIds,
                    pageIndex,
                    pageSize);
            List<CompleteTaskBoResp> completeTaskBoRespList = getCompleteTaskBoResps(taskPoRespList);
            pageBeanBoResp.setList(completeTaskBoRespList);


        }
        return pageBeanBoResp;
    }

    @Override
    public StudentTaskDetailAnalyseBoResp getStudentTaskDetailAnalyseByTestId(TaskIdBoReq taskIdBoReq) throws SQLException {


        TaskDetailPoResp taskDetail = taskDao.getTaskDetailByTaskId(taskIdBoReq.getTaskId());
        StudentTaskDetailAnalyseBoResp studentTaskDetailAnalyseBoResp =
                CommonUtil.objToObj(taskDetail,StudentTaskDetailAnalyseBoResp.class);
        studentTaskDetailAnalyseBoResp.setNumberOfComplete(taskDetail.getNumberOfComplete());
        studentTaskDetailAnalyseBoResp.setNumberOfStudent(taskDetail.getNumberOfStudent());
        int numberOfOverdue = taskDao.getNumberOfOverdueByTaskId(taskIdBoReq.getTaskId());
        studentTaskDetailAnalyseBoResp.setNumberOfOverdue(numberOfOverdue);
        //获取学生完成情况
        List<StudentTaskPoResp> studentTaskList = taskDao.getStudentTaskByTaskId(taskIdBoReq.getTaskId());

        for (int i = 0;i<studentTaskList.size();i++){
            StudentTaskPoResp stuTask = studentTaskList.get(i);

            //进行中,没有过期
            if(stuTask.getState() == 0 ){
                //判断最新状态,是否过期
                if (stuTask.getTaskExpirationDate().getTime() < new Date().getTime()) {
                    stuTask.setState(2);
                    taskDao.updateStudentTaskStateByTaskIdAndStudentId(taskIdBoReq.getTaskId(),stuTask.getStudentId(),2);
                }

            }
            StudentTaskBoResp studentTaskBoResp= CommonUtil.objToObj(stuTask,StudentTaskBoResp.class);
//            studentTaskBoResp.setCompleteTime(CommonUtil.dateSourceToString(stuTask.getCompleteTime(),CommonUtil.pattern));
            studentTaskBoResp.setTaskExpirationDate(CommonUtil.dateSourceToString(stuTask.getTaskExpirationDate(),CommonUtil.pattern));
            studentTaskDetailAnalyseBoResp.getStudentTaskList().add(studentTaskBoResp);
        }

        //分析任务中资源的完成情况
        List<TaskResourceCompletePoResp> taskResourceComplete
                = taskDao.getTaskResourceCompleteByTaskId(taskIdBoReq.getTaskId());

        taskResourceComplete.forEach(taskResourceCompletePoResp -> {
            studentTaskDetailAnalyseBoResp.getTaskResourceComplete()
                    .add(CommonUtil.objToObj(taskResourceCompletePoResp,TaskResourceCompleteBoResp.class));

        });


        return studentTaskDetailAnalyseBoResp;
    }


    /**
     * 得到学生已经学习的任务列表
     * @param studentId
     * @return
     * @throws SQLException
     */
    private List<String> getOrderedCompleteTaskIds(String studentId) throws SQLException {
        List<String> orderedCompleteTaskIdsByTeachingIds = new ArrayList<>();
        TaskListBoResp taskListBoResp = new TaskListBoResp();

            List<String> completeTaskIds = taskDao.getCompleteTaskIdsByStudentId(studentId);
            if(completeTaskIds.size()>0) {
                //得到已经学习的任务编号,排除被删除的任务
                orderedCompleteTaskIdsByTeachingIds = taskDao.getOrderedCompleteTaskIdsByStudentId(completeTaskIds);

        }
        return orderedCompleteTaskIdsByTeachingIds;
    }
}
